/*
  Contains hash table source code, where md5sum of files
  is treated as hash key and corresponding file info is
  mainitained in the form of inode. ( unsigned long long)
  Although we want to verbose everything but we show only
  matched contents find -inum <inode>
 */


#include "common.h"
#include <string>
#include <string.h>
#include <iostream>
#include <map>
#include <stack>
#include <stdlib.h>
using namespace std;

/* -> Hashtable is implemented using stl map
  Hash table
  ______
 |_key0_|->[||||||||]   stack
 |_key1_|->[||]
 |_key2_|

*/

static map <string ,stack < unsigned long long > > ht;

/*
 get stack associated with the key
 */
static void ht_get_stack(stack < uint64_t > & st)
{
    unsigned char t;
    static char cmd[MAXCMDLEN];
    while(!st.empty())
    {
	t=MAXCMDLEN;
	while(t) cmd[--t]='\0';
	sprintf(cmd,"find %s -inum %llu",gcmd,st.top());
	system(cmd); //excute find -inum <inode>	
	st.pop();
    }
}

/*
You can't have a duplicate key in a map.
more info @ http://www.cplusplus.com/reference/stl/map/
*/
void ht_insert( unsigned char *key, uint64_t value)
{
    ht[(const char *)key].push(value);
}

/* find the key & its associated values from the hash table
 */
//void ht_find(unsigned char *key,uint64_t *value)
//{
//     *value = ht.find((char *)key)->second.top();
//}

/*
 get all keys whose associated stack size is > 1.
*/
void ht_list_dups()
{
    if(!ht.size())
	return;

    map <string ,stack < uint64_t> >::iterator i;

    for( i =ht.begin(); i!= ht.end() ; i++)
    {
	if(i->second.size() == 1)
	    continue;

        int j;
	printf("DUPLICATE ENTRIES=%d HASH VALUE:",i->second.size());
        for(j=0;j<16;j++)
            printf("%02x",(unsigned char )i->first.c_str()[j]);
        ht_get_stack( i->second );
	printf("\n\n");
    }
   /*
   All the elements in the container are dropped: their destructors
   are called, and then they are removed from the container,leaving
   it with a size of 0
   */
	ht.clear();
}
